package edu.uoc.tfc.web.tags;



import java.lang.reflect.Method;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;

import org.apache.commons.lang.StringEscapeUtils;
import org.apache.log4j.Logger;
import org.apache.struts.action.ActionForm;
import org.apache.struts.config.ActionConfig;

import edu.uoc.tfc.gui.common.Level;
import edu.uoc.tfc.gui.common.MissatgeAjax;
import edu.uoc.tfc.gui.common.ResultatAccioAjaxVO;



public class AjaxResponseTag extends EmktBaseTag
{

 

    private static final long serialVersionUID = 1L;



    private static final Logger LOG = Logger.getLogger(AjaxResponseTag.class);



	private String callback;



	public String getCallback() {
		return callback;
	}

	public void setCallback(String callback) {
		this.callback = callback;
	}



	@Override
	public int doStartTag() throws JspException
	{
        try
        {
        	ActionConfig actionInstance =
                    (ActionConfig) pageContext.
                    	getRequest().getAttribute("org.apache.struts.action.mapping.instance");
    		
        	ActionForm formBean = 
        			(ActionForm) pageContext.
        				getRequest().getAttribute(actionInstance.getName());
        	
    		Object objeto = this.parseaObjeto(formBean);
    		ResultatAccioAjaxVO ajax = null;
    		
    		if (!(objeto instanceof ResultatAccioAjaxVO))
    		{
    			MissatgeAjax error =
    				new MissatgeAjax(
    					this.getMessage("error.generic.ajax.response", null),
    					null,
    					Level.Error
    				);
    			ajax = new ResultatAccioAjaxVO();
    			ajax.addMessage(error);
    		}
    		else
    		{
    			ajax = (ResultatAccioAjaxVO) objeto; 
    		}
    		
    		this.printResultadoAccionAjax(ajax);
		}
        catch (Exception e)
        {
			LOG.error("Error parseando objeto: " + this.getProperty(), e);
			throw new JspException("Error parseando objeto a JSON: " + this.getProperty());
		} 

		return SKIP_BODY;
	}



    private void printResultadoAccionAjax(ResultatAccioAjaxVO ajax) throws Exception
    {
    	JspWriter out = pageContext.getOut();

    	StringBuilder message = new StringBuilder();
    	message.append("<ul class=\"emkt-messages-list\">");
		for (MissatgeAjax m : ajax.getMessages())
		{
			switch (m.getLevel()) {
				case Error:
					message.append("<li class=\"emkt-message.error\">");
					break;
				case Warn:
					message.append("<li class=\"emkt-message.warn\">");
					break;
				case Info:
					message.append("<li class=\"emkt-message.info\">");
					break;
				case Success:
					message.append("<li class=\"emkt-message.success\">");
					break;
				default:
					message.append("<li class=\"emkt-message\">");
			}
			message.append(
				getMessage(
					m.getCodiMissatge(),
					m.getParametres()
				)
			);
			message.append("</li>");
        }
		message.append("</ul>");

		String ul = StringEscapeUtils.escapeJavaScript(message.toString());

    	write(out, "<script>");

		switch (ajax.getLevel())
		{
			case Error:
				write(out, "messages.error('" + ul + "');");
				break;
			case Warn:
				write(out, "messages.warn('" + ul + "');");
				break;
			case Info:
				write(out, "messages.info('" + ul + "');");
				break;
			case Success:
				write(out, "messages.success('" + ul + "');");
				break;
		}

    	if (getCallback() != null && getCallback().length() > 0)
    	{
    		write(out, "$.globalEval('" + getCallback() + "');");
    	}

    	write(out, "</script>");
	}



	private Object parseaObjeto(ActionForm formBean) throws Exception
	{
    	Method[] metodos = formBean.getClass().getMethods();
    	Method getter = null;
    	
    	for (int i = 0; i < metodos.length; i++)
    	{
			if (metodos[i].getName().equalsIgnoreCase("get" + this.getProperty()))
			{
				getter = metodos[i];
			}
		}

    	Object returnValue = getter.invoke(formBean, new Object[]{});
		return returnValue;
	}



	public int doEndTag() {
        return EVAL_PAGE;
    }



}
